<template>
  <DialogCom :title="'选择文件'" width="700" @close="close" @confirm="confirm">
    <template v-slot:content>
      <div>
        <!-- 头部 -->
        <div class="file-choose">
          <!-- 返回上一级 -->
          <div class="common-cursor" @click="backdirertory">
            <img src="../assets/publish/return.svg" alt="..." class="file_choose_img" />
          </div>
          <!-- 文件路径 -->
          <el-input class="choose-ipt" v-model="filePathName" @keyup.enter="getFile(filePathName, null)" />
          <!-- 刷新 -->
          <div class="common-cursor" @click="getFile(filePathName, null)">
            <img src="../assets/publish/bendigengxin.png" alt="..." />
          </div>
        </div>

        <!-- 中间:文件列表 -->
        <div class="file-list">
          <p>文件名称</p>
          <div v-for="(item, index) in fileList" :key="index" class="file-item"
            @click="getFile(item.path, null, item.type, item.name)">
            <img v-if="item.type === 'dir'" src="../assets/publish/file.png" alt="..." />
            <img v-else src="../assets/publish/file.svg" alt="..." />
            <!-- <span>{{ !filePathName ? item.path : getLastDirectory(item.path, filePathName) }}</span> -->
            <span>{{ item.name }}</span>
          </div>
        </div>

        <!-- 底部 -->
        <div class="file_bottom">
          <div>文件名称(N):</div>
          <div class="bottom-ipt">
            <el-input class="ipt" v-model="fileName" />
          </div>
          <!-- 文件类型选择 -->
          <div class="bottom-select">
            <el-select v-model="form.type" placeholder="请选择" class="selct" @change="getFile(null, form.type)">
              <el-option v-for="(item, index) in typeList" :key="index" :label="item.value" :value="item.value"
                :selected="index == 0" />
            </el-select>
          </div>
        </div>
      </div>
    </template>
  </DialogCom>
</template>
<script setup>
import DialogCom from "@/components/common/DialogCom.vue";
import { getServerFilePath } from '@/api/modelser2Api'
import { onMounted, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
const props = defineProps({
  close: {
    type: Boolean,
    default: false,
  },
  fileAccept: {
    type: String,
    default: '',
  },
  isInputOrOutput: {
    type: String,
    default: 'input',
  },
})
const emits = defineEmits(['close', 'confirm'])
const form = ref({
  type: '',
  path: '',
  name: '',
})
let prev = ref('')
const fileList = ref([])
const typeList = []
const fileName = ref('')
const filePathName = ref('')
let prevPath = ''
const AllPath = ref('')

onMounted(() => {
  getFile()
  // 如果没有传文件类型fileAccept 则默认为选择文件夹
  if (props.fileAccept) form.value.type = props.fileAccept
  const data = {
    value: props.fileAccept || 'All(*.*)',
    selected: true,
  }
  typeList.push(data)
})

function getLastDirectory(fullPath, basePath) {

  // 统一替换斜杠并移除尾部斜杠
  const normalizedBase = basePath.replace(/[\\/]+$/, '').replace(/[\\/]/g, '\\');
  const normalizedFull = fullPath.replace(/[\\/]/g, '\\');

  // 检查基础路径是否匹配
  if (!normalizedFull.startsWith(normalizedBase)) {
    return '';
  }

  // 提取相对部分并拆分路径
  const relativePath = normalizedFull.slice(normalizedBase.length);
  const parts = relativePath.split(/[\\/]+/).filter(part => part);

  // 返回最后一级目录
  if (parts.length > 0) return parts[0];
  return '';
}

const getFile = async (path, accept, wenjianType, name) => {
  //   debugger
  // if (path) {
  // if (wenjianType !== 'dir')
  // {
  //     const lastIndex = path.lastIndexOf('\\');
  //     fileName.value = path.substring(lastIndex + 1);
  //     AllPath.value = path
  //     return
  // } else
  // {
  //     // 如果是文件夹则赋值给filePathName
  //     filePathName.value = path
  //     AllPath.value = path
  // }
  // }
  // 将上一次路径filePathName保存 每次重新赋值给prev
  // prev.value = prevPath
  // prevPath = filePathName.value;
  filePathName.value = path
  AllPath.value = path
  fileName.value = ''
  if (wenjianType && wenjianType === 'file' && name) {
    fileName.value = name
    return
  }
  const params = {
    path: path ? encodeURIComponent(path) : '',
    accept: accept ? encodeURIComponent(accept) : encodeURIComponent(form.value.type),
  }
  if (!params.path) delete params.path
  const res = await getServerFilePath(params)
  if (res.status !== 'ok') return
  fileList.value = res.data.files
}

// 返回上一级
const backdirertory = () => {
  // 若文件路径为空，直接返回
  if (!filePathName.value) return
  // 将路径中的反斜杠替换为正斜杠，并去除多余的正斜杠
  const path = filePathName.value.replace(/\\/g, '/').replace(/\/+/g, '/')
  // 按正斜杠分割路径
  const pathSegments = path.split('/')
  // 移除路径数组末尾的空字符串
  while (pathSegments.length > 0 && pathSegments[pathSegments.length - 1] === '') {
    pathSegments.pop()
  }
  // 移除路径数组末尾的最后一个元素
  pathSegments.pop()
  if (pathSegments[0] !== "") {
    // 重新组合路径
    let newPath = pathSegments.join('\\')
    // 若路径是 Windows 盘符，添加反斜杠
    if (newPath.length === 2 && newPath.endsWith(':')) {
      newPath += '\\'
    }
    // 调用 getFile 函数获取新路径下的文件
    getFile(newPath, null)
  } else {
    // 重新组合路径
    let newPath = pathSegments.join('/')
    // 调用 getFile 函数获取新路径下的文件
    getFile(newPath, null)
  }

}

const close = () => {
  emits('close')
}

// 提取允许的扩展名（例如从 "fbx数据(*.fbx)|*.fbx" 提取 [".fbx"]）
function extractExtensions(fileAccept) {
  const extPattern = /\|\*\.(\w+)(?:;\*\.(\w+))?/;
  const match = fileAccept.match(extPattern);
  if (!match) return []; // 无匹配则返回空数组
  const extensions = [];
  if (match[1]) extensions.push(`.${match[1].toLowerCase()}`);
  if (match[2]) extensions.push(`.${match[2].toLowerCase()}`);
  return extensions;
}

//提取符合条件的文件
const getName = (str) => {
  const foundItem = fileList.value.find(item => {
    const itemDot = item.name.lastIndexOf('.');
    const strDot = str.lastIndexOf('.');
    // 情况1：只有 str 有 . → false
    if (strDot !== -1 && itemDot === -1) return false;
    // 情况2：两者都有 . → 必须完全相同,
    if (strDot !== -1 && itemDot !== -1) {
      if (props.fileAccept && props.fileAccept !== 'All(*.*)') {
        const allowedExtensions = extractExtensions(props.fileAccept); // 提取允许的扩展名
        const strNameLast = str.slice(strDot); // 输入的文件名后缀
        if (!allowedExtensions.includes(strNameLast)) {
          const newItemNameLast = item.name.slice(0, itemDot); // 主文件名后缀
          return str === newItemNameLast
        }
      }
      return item.name === str;
    }
    // 情况3：只有 item.name 有 . → 比较主文件名 + 检查扩展名是否符合 fileAccept
    if (itemDot !== -1) {
      const mainNameMatch = item.name.slice(0, itemDot) === str;
      if (!mainNameMatch) return false; // 主文件名不匹配

      // 如果 fileAccept 存在，检查扩展名是否匹配
      if (props.fileAccept && props.fileAccept !== 'All(*.*)') {
        const allowedExtensions = extractExtensions(props.fileAccept); // 提取允许的扩展名
        const itemExt = item.name.slice(itemDot).toLowerCase(); // 获取 .clm, .fbx 等
        return allowedExtensions.includes(itemExt);
      }
      return true; // 如果 fileAccept 未定义，直接返回 true
    }
    // 情况4：两者都没有 . → 直接比较
    if (itemDot !== -1 && strDot !== -1) {
      // 如果 fileAccept 存在，检查扩展名是否匹配
      if (props.fileAccept && props.fileAccept !== 'All(*.*)') return false
      return item.name === str;; // 如果 fileAccept 未定义，直接返回 true
    }

  });
  // 如果找到匹配项，返回 item.name，否则返回 undefined（或自定义默认值）
  return foundItem?.name
}

// 定义确认操作的函数
const confirm = () => {
  if (!filePathName.value) {
    return ElMessage.warning('请选择文件')
  }
  // 用于存储最终生成的路径
  let path

  // 从表单中获取文件类型
  const formType = form.value.type
  // 检查是否选择了文件夹类型（类型为空或为 'All(*.*)'）
  const isFolder = !formType || formType === 'All(*.*)'

  if (isFolder) {
    // 若为文件夹类型，调用 getPath 函数生成文件夹路径
    path = getPath(AllPath.value, fileName.value)
  } else {
    // 若为文件类型
    // 检查文件名是否为空，若为空则显示警告信息并终止函数执行
    if (!fileName.value) {
      return ElMessage.warning(`请选择${props.fileAccept}文件`)
    }
    const str = fileName.value.trim();
    const name = getName(str);
    if (!name) {
      return ElMessage.warning('文件不存在，请重新选择');
    }

    // 获取允许的文件扩展名列表
    const allowedExtensions = formType.split(/[|;]/)
    // 调用 ensureFileExtension 函数确保文件名包含正确的扩展名
    fileName.value = ensureFileExtension(fileName.value, allowedExtensions)
    // 调用 getPath 函数生成文件路径
    path = AllPath.value
  }

  // 根据组件属性 isInputOrOutput 判断是输出还是输入操作
  const operationType = props.isInputOrOutput
  if (operationType === 'output') {
    // 若为输出操作，触发 confirm 事件并传递路径和操作类型
    emits('confirm', path, 'output')
  } else if (operationType === 'input') {
    // 若为输入操作，触发 confirm 事件并传递路径和操作类型
    emits('confirm', path, 'input')
  }
}

// 用于生成路径的辅助函数
const getPath = (basePath, name) => {
  // 若基础路径以斜杠结尾或者文件名为空，直接拼接基础路径和文件名
  // if (basePath.endsWith('\\') || basePath.endsWith('/') || !name) {
  if (basePath.endsWith('/') || !name) {

    return basePath + name
  }
  // 否则，在基础路径和文件名之间添加反斜杠后拼接
  return basePath + '/' + name
}

// 用于确保文件名包含正确扩展名的辅助函数
const ensureFileExtension = (fileName, allowedExtensions) => {
  // 获取文件名的扩展名
  const currentExtension = fileName.includes('.') ? fileName.slice(fileName.lastIndexOf('.')) : ''
  // 检查当前扩展名是否在允许的扩展名列表中
  const hasValidExtension = allowedExtensions.includes(currentExtension)
  // 若当前扩展名不在允许列表中
  if (!hasValidExtension) {
    // 移除文件名中现有的扩展名，并添加允许列表中的第一个扩展名
    return fileName.replace(/\.[^.]*$/, '') + allowedExtensions[1].replace('*', '')
  }
  // 若扩展名合法，直接返回原文件名
  return fileName
}
</script>
<style scoped>
.file_choose_img {
  width: 21px;
  height: 21px;
}

.selct {
  background: var(--primary-white-color);
}

.choose-ipt {
  width: 50%;
  background: var(--primary-white-color);
}

img {
  padding: 0 10px;
}

.file-choose {
  display: flex;
  align-items: center;
}

.file-list {
  height: 374px;
  overflow-y: auto;
  background: var(--primary-white-color);
  margin: 10px 0;
  padding: 10px;
}

.file-item {
  display: flex;
  align-items: center;
  line-height: 31px;
  cursor: pointer;
}

.file-item:hover {
  background-color: var(--highlight-hover-color);
}

.file-item>img {
  width: 20px;
  height: 20px;
}

.file_bottom {
  display: flex;
  padding-bottom: 10px;
  box-sizing: border-box;
  align-items: center;
}

.bottom-select {
  width: 30%;
}

.bottom-ipt {
  width: 50%;
  padding: 0 10px;
}

.ipt {
  background: var(--primary-white-color);
}

.common-cursor {
  cursor: pointer;
}
</style>
